import './OverallProgress.scss'
import { CloseOutlined } from '@ant-design/icons'
import { useRef, useEffect, useState } from 'react'
import { Select, Button, Tree, Tag, Empty } from 'antd'
import { useRequest, useLocalStorageState } from 'ahooks'

import { Http } from '../../../Api'
import { NewMapUrl } from '../../../Configure/CommonParameter'

const initMars3 = {
    scene: {
        center: { lat: 45.263334, lng: 124.222042, alt: 4495185.1, heading: 360, pitch: -89.8 },
        showSun: false,
        showMoon: false,
        showSkyBox: false,
        showSkyAtmosphere: false,
        fog: false,
        backgroundColor: '#363635',
        // contextOptions: { webgl: { antialias: !mobilecheck() } },
        globe: { baseColor: '#363635', showGroundAtmosphere: false, enableLighting: false },
        clock: { currentTime: '2023-11-01 12:00:00' },
        cameraController: {
            zoomFactor: 1.5,
            minimumZoomDistance: 0.1,
            maximumZoomDistance: 200000,
            enableCollisionDetection: false,
        },
    },
    layers: [{ name: '网格线', type: 'grid', color: '#ffffff', alpha: 0.03, cells: 2, show: true }],
}
const { mars3d, Cesium } = window
const { CheckableTag } = Tag

const ModelMapping = {
    'e567faca-7e67-4e35-9b71-92dfa539a3a2': 'f1eed8fd-3240-44a8-a16d-2af9e7033911',
    '6a01d362-fd23-446f-a04c-20b6bca71883': '9b229046-25ec-4838-9043-12b5a3e95552',
}

const ColorMapping = {
    default: 'rgba(255,255,255,1)',
    select: 'rgba(0,255,0,1)',
    hidden: 'rgba(255,255,255,0.1)',
}

export const OverallProgress = () => {
    const [ClientData] = useLocalStorageState('ClientData')
    const MapDiv = useRef()
    const [Map, setMap] = useState()
    const [Gra, setGra] = useState()
    const [Json, setJson] = useState()
    const [ModelList, setModelList] = useState()
    const [ModelTree, setModelTree] = useState()
    const [Active, setActive] = useState()
    const [Tiles, setTiles] = useState()

    const [RightData, setRightData] = useState()

    const { runAsync: getJson } = useRequest(Http, {
        manual: true,
        onSuccess: res => {
            if (res) setJson(res)
            else
                posJson({
                    url: 'posSaveJsonInfoByUuid',
                    data: JSON.stringify(JSON.stringify({})),
                    path: ['OverallProgress'],
                })
        },
    })

    const { runAsync: getModel } = useRequest(Http, { manual: true, onSuccess: res => setModelList(res.list) })
    const { runAsync: getTree } = useRequest(Http, { manual: true, onSuccess: res => setModelTree(res[0].children) })
    const { runAsync: getTreeItem } = useRequest(Http, {
        manual: true,
        onSuccess: (res, [pro]) => {
            setRightData({ title: pro.data.title, value: res.list })
            // 模型染色
            DbIdRenderColor(res.list, Json[pro.data.FilesUuid])
        },
    })

    const { runAsync: posJson } = useRequest(Http, {
        manual: true,
        onSuccess: () => getJson({ url: 'getJsonInfoByUuid', data: { uuid: 'OverallProgress' } }),
    })

    const initMapFunc = data => {
        const map = new mars3d.Map(MapDiv.current, initMars3)
        const gra = new mars3d.layer.GraphicLayer()
        setMap(map)
        setGra(gra)
        // 获取模型列表
        getModel({ url: 'getBimFileOrganizationRelation' })
        getTree({ url: 'getconstructionTrees', path: Object.keys(ClientData.project) })
    }

    const initModal = uuid => {
        const { url } = ModelList.find(v => v.bimFilesUuid === uuid)
        const SelectData = Json[uuid] || []
        // eslint-disable-next-line no-template-curly-in-string
        const SelectDbId = SelectData.map(item => ['${DbId}===' + item, ColorMapping.select])
        // 生成图层
        if (Tiles) Map.removeLayer(Tiles)
        const tiles = new mars3d.layer.TilesetLayer({
            id: uuid,
            flyTo: true,
            clampToGround: true,
            url: NewMapUrl + url,
            style: { color: { conditions: [...SelectDbId, ['true', ColorMapping.default]] } },
            allowDrillPick: e => {
                const alpha = e.pickedObject.color.alpha
                if (Cesium.defined(alpha) && alpha !== 1) return true
                return false
            },
        })
        Map.addLayer(tiles)
        setTiles(tiles)
    }

    const DbIdRenderColor = (resData, selData) => {
        const resDataArray = resData.filter(item => !selData.includes(item.dbId))
        const selDataArray = selData.filter(item => resData.some(obj => obj.dbId === item))
        // eslint-disable-next-line no-template-curly-in-string
        const dbidList = resDataArray.map(({ dbId }) => ['${DbId}===' + dbId, ColorMapping.default])
        // eslint-disable-next-line no-template-curly-in-string
        const dbidSele = selDataArray.map(dbId => ['${DbId}===' + dbId, ColorMapping.select])
        Tiles.style = new Cesium.Cesium3DTileStyle({
            color: { conditions: [...dbidList, ...dbidSele, ['true', ColorMapping.hidden]] },
        })

        // console.log('[resData]', resData)
        // console.log('[selData]', selData)
    }

    useEffect(() => {
        initMapFunc()
        getJson({ url: 'getJsonInfoByUuid', data: { uuid: 'OverallProgress' } })
        return () => {
            if (Map) Map.destroy()
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [])

    const onModelSelect = e => {
        setRightData()
        setActive(e)
        initModal(e)
    }

    const onTreeSelect = (_, { node }) => {
        const { fullName, uuid, lowLevel } = node
        if (lowLevel === 0) {
            setRightData()
            getTreeItem({
                url: 'getModelsInfo',
                data: { FilesUuid: Active, constructionTreeUuid: uuid, title: fullName },
            })
        }
    }

    const onClose = () => {
        setRightData()
        initModal(Active)
    }

    const onItemClick = (dbid, checked) => {
        const jsonData = Json[Active] || []
        const nextSelectedTags = checked ? [...jsonData, dbid] : jsonData.filter(v => v !== dbid)
        setJson({ ...Json, [Active]: nextSelectedTags })
        DbIdRenderColor(RightData.value, nextSelectedTags)
    }

    const onSubmit = () => {
        posJson({ url: 'posSaveJsonInfoByUuid', data: JSON.stringify(JSON.stringify(Json)), path: ['OverallProgress'] })
    }

    return (
        <div className="OverallProgress">
            <div className="Map" ref={MapDiv} />
            <div className="top">
                <Select
                    options={ModelList}
                    placeholder="请选择BIM模型"
                    fieldNames={{ label: 'bim_FilesName', value: 'bimFilesUuid' }}
                    onChange={onModelSelect}
                />
                {Tiles && (
                    <>
                        <Button type="primary" ghost onClick={() => Map.flyToGraphic(Tiles)}>
                            视角回归
                        </Button>
                        <Button type="primary" onClick={onSubmit}>
                            保存数据
                        </Button>
                    </>
                )}
            </div>

            {ModelTree && Active && (
                <div className={`left animate__animated ${Active ? 'animate__fadeInLeft' : 'animate__fadeOutLeft'}`}>
                    <Tree
                        blockNode={true}
                        className="treeDele"
                        treeData={[ModelTree.find(v => v.uuid === ModelMapping[Active])]}
                        fieldNames={{ title: 'tableName', key: 'uuid' }}
                        onSelect={onTreeSelect}
                    />
                </div>
            )}
            {RightData && (
                <div className={`right animate__animated ${Active ? 'animate__fadeInRight' : 'animate__fadeOutRight'}`}>
                    <div className="title">
                        <div>{RightData.title}</div>
                        <CloseOutlined onClick={onClose} />
                    </div>
                    <div className="list">
                        {RightData.value.length === 0 ? (
                            <Empty />
                        ) : (
                            RightData.value.map(({ dbId, tableName }) => {
                                return (
                                    <CheckableTag
                                        key={dbId}
                                        checked={Json[Active]?.includes(dbId)}
                                        onChange={e => onItemClick(dbId, e)}
                                    >
                                        {tableName}
                                    </CheckableTag>
                                )
                            })
                        )}
                    </div>
                </div>
            )}
        </div>
    )
}
